
package horde.internalResources.editor;

import horde.internalResources.dictionaries.dictionary;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.table.DefaultTableModel;

/**
 * @author Andres Picazo
 * @author Arturo Mazon
 */
public class Editor extends JFrame {

    protected Dimension screenSize, twoThirds;
    protected JPanel sidePanel, mainPanel, automatonPanel;
    protected JTabbedPane agentPane;
    protected JFileChooser fc;
    private ButtonHandler bh;
    /* Storage */
    private ArrayList<File> Cores;
    private ArrayList<File> Automatons;
    private ArrayList<File> Manifests;
    /* Left panel buttons */
    protected JButton b_main, b_fsm;
    /* Main panel (scanner) elements */
    protected JTextField scanPathField;
    protected JButton b_scan, b_lookFor;
    protected JTable scanTable;
    protected DefaultTableModel scanTableModel;
    protected JLabel results;

    public Editor (String locale) {
        super();
        try {
            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (Exception e) {}
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        screenSize = getToolkit().getScreenSize();
        twoThirds = new Dimension(screenSize.width*2/3, screenSize.height*2/3);
        dictionary.setBundle(locale);

        setTitle (dictionary.getString("editor.title"));
        setSize (twoThirds);
        setLayout(new BorderLayout());
        setLocationRelativeTo(null);
        init();
        setVisible(true);
    }

    private void init () {
        /* Any number of rows, only one column */
        bh  = new ButtonHandler(this);
        createButtons();
        createMainPanel ();
        createAutomatonPanel ();
    }

    private void createButtons () {
        sidePanel = new JPanel(new GridLayout(6,1));
        ArrayList<JButton> buttonList = new ArrayList<JButton>();
        buttonList.add(b_main = new JButton ("Scanner"));
        buttonList.add(b_fsm = new JButton ("FSM"));

        /* Set default properties */
        for (JButton b : buttonList) {
            b.setPreferredSize(new Dimension (80,80));
            b.addActionListener(bh);
            sidePanel.add (b);
        }
        add (sidePanel, BorderLayout.LINE_START);
    }

    private void createMainPanel() {
        fc = new JFileChooser();
        fc.setCurrentDirectory(new File("."));
        mainPanel = new JPanel(new BorderLayout());
        JPanel scannerPanel = new JPanel (new FlowLayout(FlowLayout.LEFT));
        scannerPanel.add (new JLabel(dictionary.getString("editor.sourcePath")));
        scanPathField = new JTextField(fc.getCurrentDirectory().toString());
        scanPathField.setPreferredSize(new Dimension(300,25));
        b_scan = new JButton (dictionary.getString("editor.scanButton"));
        b_scan.addActionListener(bh);
        b_lookFor = new JButton ("...");
        b_lookFor.addActionListener(bh);
        scannerPanel.add(scanPathField);
        scannerPanel.add(b_scan);
        scannerPanel.add(b_lookFor);
        mainPanel.add (scannerPanel, BorderLayout.NORTH);

        /* Table */
        scanTable = new JTable() {
            @Override public boolean isCellEditable (int row, int column) {
                return false;
            }
        };
        scanTableModel = new DefaultTableModel();
        scanTableModel.addColumn(dictionary.getString("editor.scan.elementName"));
        scanTableModel.addColumn(dictionary.getString("editor.scan.elementType"));
        scanTableModel.addColumn(dictionary.getString("editor.scan.elementPath"));
        scanTable.setModel(scanTableModel);
        scanTable.getColumnModel().getColumn(1).setMaxWidth(200);
        JScrollPane sp = new JScrollPane(scanTable);
        sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        mainPanel.add (sp, BorderLayout.CENTER);
        mainPanel.add (results = new JLabel("  "), BorderLayout.PAGE_END);
        add (mainPanel, BorderLayout.CENTER);
    }

    private void createAutomatonPanel () {
        automatonPanel = new AutomatonPanel();
        add (automatonPanel, BorderLayout.CENTER);
//        ((AutomatonPanel)automatonPanel).newStateDemo();
//        ((AutomatonPanel)automatonPanel).newStateDemo();
//        ((AutomatonPanel)automatonPanel).newStateDemo();
//        ((AutomatonPanel)automatonPanel).newStateDemo();

    }

    /* ---------------------------------------------------------------------- */

    private void scan () {
        File path = new File (scanPathField.getText());
        if (path.exists() && path.canRead() && path.isDirectory()) {
            File [] content = path.listFiles();
            for (File f : content) {
                processPath (f);
            }
        } else {
            JOptionPane.showConfirmDialog(this, dictionary.getString("editor.pathError"));
        }
        String t = "Core: " + Cores.size() + " FSM: " + Automatons.size() + " Manifest: " + Manifests.size() +
                " Other: " + (scanTableModel.getRowCount() - Cores.size() - Automatons.size() - Manifests.size());
        results.setText(t);        
    }

    private void processPath (File f) {
        if (f.exists() && f.canRead()) {
            File [] content = f.listFiles();
            for (File child : content) {
                if (child.isDirectory()) processPath(child);
                else if (child.isFile()) {
                    String name = child.getName();
                    String type = "File";
                    String path = child.getPath();
                    String processedPath = path.replaceAll("%20", " ");
                    try {
                        if (processedPath.contains(".java")) {
                            type = "Java File";
                            Scanner sc = new Scanner(new File (processedPath));
                            if (sc.findWithinHorizon("extends Core",0) != null) {
                                type = "Horde Core";
                                Cores.add(child);
                            }
                        } else if (processedPath.contains(".xml")) {
                            type = "XML";
                            Scanner sc = new Scanner(new File (processedPath));
                            if (sc.findWithinHorizon("<FSM>",0) != null) {
                                type = "Automaton XML";
                                Automatons.add(child);
                            }
                            else if (sc.findWithinHorizon("<manifest>",0) != null) {
                                type = "Manifest XML";
                                Manifests.add(child);
                            }
                        }
                    } catch (Exception e) {} 
                    Object [] row = {name, type, path};
                    scanTableModel.addRow(row);
                }
            }
        }
    }

    private class ButtonHandler implements ActionListener {

        private JFrame parentFrame;

        public ButtonHandler (JFrame parent) {
            parentFrame = parent;
        }

        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == b_lookFor) {
                int oldMode = fc.getFileSelectionMode();
                fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                if (fc.showDialog(null, "OK") == JFileChooser.APPROVE_OPTION) {
                    scanPathField.setText(fc.getSelectedFile().toString());
                } fc.setFileSelectionMode(oldMode);
            }
            else if (e.getSource() == b_scan) {
                while (scanTableModel.getRowCount() > 0) scanTableModel.removeRow(0);
                Cores = new ArrayList<File>();
                Automatons = new ArrayList<File>();
                Manifests = new ArrayList<File>();
                scan();
            }
            else if (e.getSource() == b_main) {
                parentFrame.add (mainPanel, BorderLayout.CENTER);
                automatonPanel.setVisible(false);
                mainPanel.setVisible(true);
            }
            else if (e.getSource() == b_fsm) {
                parentFrame.add (automatonPanel, BorderLayout.CENTER);
//                parentFrame.update(parentFrame.getGraphics());
                automatonPanel.setVisible(true);
                mainPanel.setVisible(false);
            }
        }
    }
}
